package com.aliyun.iot.demo.iothub;

import java.util.ArrayList;

import com.fazecast.jSerialComm.*;

public class ReadSerialPort implements DataProvider, Runnable {

	private Thread t;
	private String threadName;

	private SerialPort serialPort = null;

	public float[] FAcc = new float[4];
	public float[] FGyro = new float[4];
	public float[] FAngle = new float[4];
	
	private float MAXAcc = 0;

	public ReadSerialPort(String PortName) {

		threadName = PortName;
		SerialPort[] ports = SerialPort.getCommPorts();
		for (SerialPort port : ports) {
			System.out.println(port.getPortDescription());
			if (port.getSystemPortName().equals(PortName)) {
				serialPort = port;
			}
		}

		if (serialPort.openPort())
			System.out.println("Port opened successfully.");
		else {
			System.out.println("Unable to open the port.");
			return;
		}
		serialPort.setComPortParameters(115200, 8, 1, SerialPort.NO_PARITY);
		serialPort.setComPortTimeouts(SerialPort.TIMEOUT_NONBLOCKING, 0, 0);
		System.out.println("step1");

		// serialPort.closePort();
		// System.out.println("Done.");
	}

	public ReadSerialPort() {

	}

	public ArrayList<String> getPortNameList() {
		SerialPort[] ports = SerialPort.getCommPorts();
		ArrayList<String> portNameList = new ArrayList<String>(10);
		for (SerialPort port : ports) {
			portNameList.add(port.getSystemPortName());
		}
		return portNameList;
	}

	@Override
	public void start() {
		// TODO Auto-generated method stub
		// TODO: 创建线程 开始跑
		if (t == null) {
			t = new Thread(this, threadName);
			t.start();
		}
	}

	@Override
	public void stop() {
		// TODO Auto-generated method stub
		// TODO: 关闭线程
		if (t != null) {
			t.interrupt();
			serialPort.closePort();
		}
	}

	@Override
	public Sample fetch() {
		// TODO Auto-generated method stub
		return new DataProvider.Sample(FAcc, FGyro, FAngle);
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		System.out.println("RUN!");
		short[] Acc = { 0, 0, 0, 0 };
		short[] Gyro = { 0, 0, 0, 0 };
		short[] Angle = { 0, 0, 0, 0 };
		while (!Thread.currentThread().isInterrupted()) {
			try {
				while (true) {
					while (serialPort.bytesAvailable() == 0)
						Thread.sleep(1);
					byte[] readBuffer = new byte[serialPort.bytesAvailable()];
					int numRead = serialPort.readBytes(readBuffer, readBuffer.length);
					while (numRead >= 11) {
						if (readBuffer[0] != 0x55) {
							numRead--;
							System.arraycopy(readBuffer, 1, readBuffer, 0, numRead);
							continue;
						}
						byte[] data = new byte[8];
						System.arraycopy(readBuffer, 2, data, 0, 8);
						switch (readBuffer[1]) {
						case 0x51:
							Acc = Utility.toShortArray(data);
							break;
						case 0x52:
							Gyro = Utility.toShortArray(data);
							break;
						case 0x53:
							Angle = Utility.toShortArray(data);
							break;
						}
						numRead -= 11;
						System.arraycopy(readBuffer, 11, readBuffer, 0, numRead);
					}
					for (int j = 0; j < 4; j++) {
						float acc = Acc[j];
						FAcc[j] = acc * 16 / 32768;
						
						float gyro = Gyro[j];
						FGyro[j] = gyro * 2000 / 32768;
						
						float angle = Angle[j];
						FAngle[j] = angle * 180 / 32768;
					}
					float flag=FAcc[0]*FAcc[0]+FAcc[1]*FAcc[1]+FAcc[2]*FAcc[2];
					if(MAXAcc<flag) {
						MAXAcc=flag;
						System.out.println("MAXAcc: "+ MAXAcc);
					}
					//System.out.println("Acc: " + FAcc[0] + " , " + FAcc[1] + " , " + FAcc[2] + "\n");
					//System.out.println("Gyro: " + FGyro[0] + " , " + FGyro[1] + " , " + FGyro[2] + "\n");
					//System.out.println("Angle: " + FAngle[0] + " , " + FAngle[1] + " , " + FAngle[2] + "\n");
				}
			} catch (InterruptedException e) {
				Thread.currentThread().interrupt();
			}
		}
	}
}
